package com.corticon.dialogs.model;

import com.corticon.dialogs.util.GenericFunction;
import java.io.Serializable;
import java.util.*;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.persistence.UniqueConstraint;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.validator.NotEmpty;

/**
 * QuestionSet entity.
 * 
 * @author Yanglifan
 */
@Entity
@Table(name = "q_page", uniqueConstraints = {@UniqueConstraint(columnNames = {"ID", "VERSION"})})
public class QuestionSet extends QuestionBase implements Serializable, QuestionAvailable {

    private Long questionSetId;

    // ********** QuestionSet Properties ********** //
    private QuestionSet sibling;
    private Set<QuestionInSet> questionsInSet = new HashSet<QuestionInSet>();
    private Set<QuestionSetInNaire> quesitonSetInNaires = new HashSet<QuestionSetInNaire>();

    // ********** Other Properties ********** //
    private String displayTitle;
    private String mediaUrl;
    private QuestionStatusType status;
    private QuestionAvailabilityType availability;
    private String listdisplayTitle;

    public QuestionSet() {
    }

    public QuestionSet(String refId, long version, QuestionSet sibling, String displayTitle, String mediaUrl,
                       QuestionStatusType status, QuestionAvailabilityType availability) {
        this.refId = refId;
        this.version = version;
        this.sibling = sibling;
        this.displayTitle = displayTitle;
        this.mediaUrl = mediaUrl;
        this.status = status;
        this.availability = availability;
    }

    @Id
    @SequenceGenerator(name = "q_page_id_seq", sequenceName = "q_page_id_seq",
            allocationSize = 1, initialValue = 1)
    @GeneratedValue(strategy = GenerationType.AUTO, generator = "q_page_id_seq")
    @Column(name = "q_page_id", columnDefinition = "integer")
    public Long getQuestionSetId() {
        return this.questionSetId;
    }

    public void setQuestionSetId(Long questionSetId) {
        this.questionSetId = questionSetId;
    }

    // ********** QuestionSet Accessors ********** //
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "siblingpageassoc_q_page_id_oid")
    public QuestionSet getSibling() {
        return this.sibling;
    }

    public void setSibling(QuestionSet sibling) {
        this.sibling = sibling;
    }

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy = "questionSet")
    @OrderBy("priority asc")
    public Set<QuestionInSet> getQuestionsInSet() {
        return this.questionsInSet;
    }

    public void setQuestionsInSet(Set<QuestionInSet> questionsInSet) {
        this.questionsInSet = questionsInSet;
    }

    @OneToMany(mappedBy = "questionSet")
    public Set<QuestionSetInNaire> getQuesitonSetInNaires() {
        return quesitonSetInNaires;
    }

    @Transient
    public List<QuestionInSet> getSortedQuestions() {
        List<QuestionInSet> sortedQuestions = new ArrayList<QuestionInSet>(this.questionsInSet);
        Collections.sort(sortedQuestions);
        return sortedQuestions;
    }

    public void setQuesitonSetInNaires(Set<QuestionSetInNaire> quesitonSetInNaires) {
        this.quesitonSetInNaires = quesitonSetInNaires;
    }

    // ********** Other Accessors ********** //
    @NotEmpty(message = "validate.questionSet.displayTitle.notEmpty")
    @Column(name = "displaytitle", length = 256)
    public String getDisplayTitle() {
        return this.displayTitle;
    }

    public void setDisplayTitle(String displayTitle) {
        this.displayTitle = displayTitle;
    }

    @Column(name = "mediaurl", length = 256)
    public String getMediaUrl() {
        return this.mediaUrl;
    }

    public void setMediaUrl(String mediaUrl) {
        this.mediaUrl = mediaUrl;
    }

    @Override
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "statusassoc_code_oid", nullable = false)
    public QuestionStatusType getStatus() {
        return this.status;
    }

    public void setStatus(QuestionStatusType status) {
        this.status = status;
    }

    @Override
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "availabilityassoc_code_oid")
    public QuestionAvailabilityType getAvailability() {
        return this.availability;
    }

    public void setAvailability(QuestionAvailabilityType availability) {
        this.availability = availability;
    }

    GenericFunction genFunction = new GenericFunction();

    @Transient
    public String getListdisplayTitle() {
        if (displayTitle != null) {
            return genFunction.interceptStr(displayTitle, 66);
        } else {
            return displayTitle;
        }
    }

    public void setListdisplayTitle(String listdisplayTitle) {
        this.listdisplayTitle = listdisplayTitle;
    }
}